#include <string.h>
#include <iostream>
using std::cout;
using std::endl;


class String
{
public:
    String()
    /* : _pstr(nullptr) */
    : _pstr(new char[1]())
    {
        cout << "String()" << endl;
    }

    String(const char *pstr)
    : _pstr(new char[strlen(pstr) + 1]())
    {
        cout << "String(const char *)" << endl;
        strcpy(_pstr, pstr);
    }

    //String s2 = s1;
    String(const String & rhs)
    : _pstr(new char[strlen(rhs._pstr) + 1]())
    {
        cout << "String(const String &)" << endl;
        strcpy(_pstr, rhs._pstr);
    }

    //String s1 = String("hello");
    String(String && rhs)
    : _pstr(rhs._pstr)
    {
        cout << "移动构造" << endl;
        rhs._pstr = nullptr;
    }

    String & operator=(String && rhs){
        cout << "移动赋值函数" << endl;
        if(this != &rhs){//自赋值的判断有意义
            delete [] _pstr;
            //浅拷贝
            _pstr = rhs._pstr;
            rhs._pstr = nullptr;
        }
        return *this;
    }

    String & operator=(const String & rhs)
    {
        cout << "String &operator=(const String &)" << endl;
        if(this != &rhs)
        {
            if(_pstr)
            {
                delete [] _pstr;
            }
            _pstr = new char[strlen(rhs._pstr) + 1]();
            strcpy(_pstr, rhs._pstr);
        }
        return *this;
    }

    size_t length() const
    {
        size_t len = 0;
        if(_pstr)
        {
            len = strlen(_pstr);
        }

        return len;

    }

    const char * c_str() const
    {
        if(_pstr)
        {
            return _pstr;
        }
        else
        {
            return nullptr;
        }
    }


    ~String()
    {
        cout << "~String()" << endl;
        if(_pstr)
        {
            delete [] _pstr;
            _pstr = nullptr;
        }
    }

    void print() const
    {
        cout << "_pstr = " << _pstr << endl;
    }

private:
    char * _pstr;
};

void test1(){
    String s1("hello");
    s1 = String("wangdao");
    s1.print();

    cout << endl;
    String("hello") = String("hello");

    cout << endl;
    String s2("world");
    s1 = s2;
    s1.print();
}


void test0(){
    //移动构造本质是移交管理权
    String s3 = String("hello");
    String s4 = s3;
}

void test2() {
    int a = 1;
    cout << &a << endl;

    /* &(std::move(a)); //error，左值转成了右值 */
    cout << std::move(a) << endl;//理解为强制转换，返回值为右值
    /* int && ref = a;//a本身还是左值 */
    cout << &a << endl;


    int && ref = std::move(a);
    cout << &ref << endl;

    ref = 10;
    cout << a << endl;
    cout << &ref << endl;
    cout << &a << endl;

    cout << endl;
	String s1("hello");
    s1.print();
    //如果经历了std::move的强转后没有进行修改操作
    //之后s1对象还是可以正常使用的
    std::move(s1);
    s1.print();

    //调用移动构造
    //在移动构造函数中形参String && rhs = std::move(s1)
    //rhs._pstr = nullptr;
    //会s1对象本身的_pstr变成空指针
	String s2 = std::move(s1);
    s1.print();//这里程序中断
    s2.print();
}

//探讨移动赋值函数中的自赋值判断是否有必要
void test3(){
    String s1("hello");
    s1 = std::move(s1);
    s1.print();
    cout << "11111111" << endl;
}


int main(void){
    test3();
    return 0;
}
